package cn.springcloud.fix.quartz.util;

import cn.springcloud.fix.quartz.config.QuartzManager;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Slf4j
public class QuartzUtil {

    /**
     * 创建定时任务
     */
    public static void createScheduleJob(Scheduler scheduler, Class<? extends Job> clazz, String jobId, String group, String cronExpression) {
        try {
            JobKey jobKey = new JobKey(jobId, group);
            if (scheduler.getJobDetail(jobKey) != null) return;
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).build();
            //放入参数，运行时的方法可以获取
            jobDetail.getJobDataMap().put(QuartzManager.JOB_PARAM_KEY, jobId);
            jobDetail.getJobDataMap().put(QuartzManager.CORN_EXPRESSION, cronExpression);
            //表达式调度构建器
            CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
            //按新的cronExpression表达式构建一个新的trigger
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobId, group).withSchedule(cronSchedule).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public static Date getNextFireTime(Scheduler scheduler, String jobId, String group) throws SchedulerException {
        TriggerKey triggerKey = new TriggerKey(jobId, group);
        Trigger trigger = scheduler.getTrigger(triggerKey);
        return trigger.getNextFireTime();
    }

    /**
     * 更新定时任务,要考虑多节点问题
     */
    public static void updateScheduleJob(Scheduler scheduler, String jobId, String jobGroup, String cronExpression) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(jobId, jobGroup);
        //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        //表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
        //按新的cronExpression表达式重新构建trigger
        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
        //按新的trigger重新设置job执行
        scheduler.rescheduleJob(triggerKey, trigger);
    }

    /**
     * 暂停任务,考虑到多节点问题,以数据库状态为准
     */
    public static boolean pauseJob(Scheduler scheduler, String jobId, String jobGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobId, jobGroup);
            scheduler.pauseJob(jobKey);
            return true;
        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 恢复任务,考虑到多节点问题,以数据库状态为准
     */
    public static boolean resumeJob(Scheduler scheduler, String jobId, String jobGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobId, jobGroup);
            scheduler.resumeJob(jobKey);
            return true;
        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 删除任务
     */
    public static void deleteJob(Scheduler scheduler, String jobId, String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobId, jobGroup);
        scheduler.deleteJob(jobKey);
    }

    /**
     * 按组删除任务
     */
    public static boolean deleteJobs(Scheduler scheduler, String jobGroup) throws SchedulerException {
        GroupMatcher<JobKey> matcher = GroupMatcher.groupEquals(jobGroup);
        Set<JobKey> jobkeySet = scheduler.getJobKeys(matcher);
        return scheduler.deleteJobs(new ArrayList<>(jobkeySet));
    }

    /**
     * 立即运行
     */
    public static void triggerJob(Scheduler scheduler, String jobId, String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobId, jobGroup);
        scheduler.triggerJob(jobKey);
    }

    /**
     * 获取一个组内的所有job
     */
    public static List<? extends Trigger> getJob(Scheduler scheduler, String jobId, String jobGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobId, jobGroup);
            return scheduler.getTriggersOfJob(jobKey);
        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
}
